import React, { useEffect, useRef, useState } from 'react';
import './index.css';

interface CalendarProps{
  value?: Date;
  defaultValue?: Date;
  onChange?: (date: Date) => void;
}


function useMergeState<T>(
    defaultSaveState: T,
    props?: {
        defaultValue: T | undefined,
        value?: T,
        onChange?: (value: T) => void
    }
): [T, React.Dispatch<React.SetStateAction<T>>,] {
    const {
        value: propsValue,
        defaultValue,
    } = props || {};

    const isFirstRender = useRef(true)
    const [stateValue, setStateValue] = useState<T>(() => {
        if (propsValue !== undefined) {
            // 受控，组件完全由propsValue决定
            return propsValue
        } else if (defaultValue !== undefined) {
            // 非受控，这里返回默认值，
            return defaultValue
        } else {
            return defaultSaveState
        }
    });

    useEffect(() => {
        // 外部value值从其他变成了undefined
        if (propsValue === undefined && !isFirstRender.current) {
            // 不是首次渲染，value变成undefined，从受控切换为非受控
            // 加了这个!是非空断言
            setStateValue(propsValue!)
        }
        isFirstRender.current = false
    }, [propsValue])

    const mergedValue = propsValue === undefined ? stateValue : propsValue
    return [
        mergedValue,
        setStateValue
    ]
}

function Calendar(props: CalendarProps) {
  // 组件也需考虑受控与非受控
  // 更加偏向于受控，这里的初始状态是父组件提供，状态的修改也是父组件去修改
  const {
    value: propsValue,
    defaultValue,
    onChange,
  } = props;

  const [mergedValue, setStateValue] = useMergeState<Date>(new Date(), {
    value: propsValue,
    defaultValue
  });

  function changeValue(date: Date) {
    // 非受控
    if (propsValue === undefined) {
        setStateValue(date)
    }
    onChange?.(date);
  } 


  return <div>
    {mergedValue && mergedValue.toLocaleDateString()}
    <div onClick={()=> {changeValue(new Date('2024-5-1'))}}>2023-5-1</div>
    <div onClick={()=> {changeValue(new Date('2024-5-2'))}}>2023-5-2</div>
    <div onClick={()=> {changeValue(new Date('2024-5-3'))}}>2023-5-3</div>
  </div>
}

function App() {
    // 受控
    const [value, setValue] = useState(new Date('2024-5-1'))
    return <Calendar value={value} onChange={(date) => {
        console.log(date.toLocaleDateString());
        setValue(date)
    }}/>
    // 非受控
    // return <Calendar defaultValue={new Date('2024-5-1')} onChange={(date) => {
    //     console.log(date.toLocaleDateString());
    // }}/>
}

export default App;
